package storages

import (
	"github.com/pkg/errors"
	"gluenet/internal/glue-srvm/model"
	"gluenet/internal/glue-srvm/pkg/gluehttp"
	"gorm.io/gorm"
)

type rechargeOrderStorage struct{}

var DefaultRechargeOrderStorageStorage = &rechargeOrderStorage{}

func (c *rechargeOrderStorage) Insert(db *gorm.DB, data model.MeteringRechargeOrder) (uint, error) {
	return uint(data.Id), errors.WithStack(db.Create(&data).Error)
}

func (c *rechargeOrderStorage) Update(db *gorm.DB, filter, data model.MeteringRechargeOrder) error {
	return errors.WithStack(db.Model(data).Where(&filter).Updates(&data).Error)
}

func (c *rechargeOrderStorage) DeleteByID(db *gorm.DB, id uint) error {
	if id == 0 {
		return errors.New("ID cannot be empty.")
	}
	return errors.WithStack(db.Delete(&model.MeteringRechargeOrder{Id: uint64(id)}).Error)
}

func (c *rechargeOrderStorage) FindOne(db *gorm.DB, filter model.MeteringRechargeOrder) (*model.MeteringRechargeOrder, error) {
	var rechargeOrder model.MeteringRechargeOrder
	err := db.Where(&filter).Find(&rechargeOrder).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, nil
	}
	return &rechargeOrder, errors.WithStack(err)
}

func (c *rechargeOrderStorage) FindAll(db *gorm.DB, filter model.MeteringRechargeOrder) ([]model.MeteringRechargeOrder, error) {
	var rechargeOrders []model.MeteringRechargeOrder
	err := db.Where(&filter).Find(&rechargeOrders).Error
	if err != nil && err == gorm.ErrRecordNotFound {
		return nil, errors.WithStack(err)
	}
	return rechargeOrders, nil
}

func (c *rechargeOrderStorage) FindPage(db *gorm.DB, filter model.RechargeOrderReq) ([]model.MeteringRechargeOrder, *gluehttp.PageResponse, error) {
	db = db.Table(model.MeteringRechargeOrder{}.TableName())
	db = db.Where("deleted_at IS NULL")
	db = db.Order("created_at DESC")
	var total int64
	if err := db.Count(&total).Error; err != nil {
		return nil, nil, err
	}
	pageResponse := &gluehttp.PageResponse{
		PageRequest: &filter.PageRequest,
		Total:       int(total),
	}
	pageResponse.SetTotal(int(total))
	var list []model.MeteringRechargeOrder
	if filter.PageSize != 0 {
		db = db.Offset(filter.Offset()).Limit(filter.PageSize)
	}
	return list, pageResponse, db.Find(&list).Error
}
